package mathy.wili.extract_srcFile.java;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
import _a.Config26;
import mathy.c.Ca;
import mathy.wili.autoeq.Refs;
import mathy.wili.c.Class9;
import mathy.wili.c.asm.Asm9;
import mathy.wili.c.asm.AsmItems.AsmItem;
/**
 * 
 * @author weila 2021年2月17日
 */
public class Visit26 {
	private static Set<String> SET50 = new HashSet<>();
	/**
	 *   
	 */
	public static MethodRange visitMethod(String fromMsg, Class<?> clazz, Executable method) {
		String mString = method.toString();
		if (mString.contains("ObjToStrSet"))
			//if (clazz.isAssignableFrom(method.getDeclaringClass()))
			Refs.visitAtt();
		int depth = 1;
		//访问是为了打访问标记
		int inc2 = ++inc;
		if (inc2 == 99)
			Ca.pause();
		Ca.debug(1, inc2, ",", fromMsg, "\t", "VisitMethod.visitMethod:", Class9.strOfMethod(method));
		{//避免重复访问
			if (!SET50.add(mString))
				return null;
		}
		RangesOfClsMember memRange = RangesOfClsMember.getInst(depth, clazz);
		if (memRange == null && Refs.NULL())
			return null;
		memRange.visited = true;
		MethodRange mrange = memRange.getMethodRange(method);
		if (mrange == null && Refs.NULL())
			return null;
		if (mrange.visited)
			return null;
		mrange.setVisited();
		Coms26.visitSuperAbstractMethodOf(mrange.getMethod());
		++CodeExtract.curVersionId;
		return mrange;
	}

	public static MethodRange visitMethodAndItsContent(Class<?> clazz, Executable method) {
		visitMethod("", clazz, method);
		AsmItemList toList = new AsmItemList(null);
		Asm9.findInMethod_forCalledMethods_and_fields(clazz, method, null, Config26.Class_filter, toList);
		toList.vistItmes(0);
		return null;
	}

	/**
	 * 	访问方法，然后深入访问方法内容
	 */
	public static void visitMethod_and_deepVisit_methodContent(int depth, AsmItem item) {
		Executable method = item.get();
		visitMethod("", method.getDeclaringClass(), method);
		deepVisit_methodContent(depth, item);
	}

	static void deepVisit_methodContent(int depth, AsmItem fromItem) {
		Executable method = fromItem.get();
		Class<?> cls = method.getDeclaringClass();
		AsmItemList toList = new AsmItemList(fromItem);
		if (method.getName().endsWith("findPutField"))
			Ca.pause();
		Asm9.findInMethod_forCalledMethods_and_fields(cls, method, null, Config26.Class_filter, toList);
		if (toList.id == -159)
			Ca.pause();
		toList.print(-1);
		toList.deepVisit(depth);
		if (method.getName().equals("visitMethod"))
			Ca.pause();
		Ca.pause();
	}

	/**
	 * 	访问属性本身
	 */
	public static void visitField(int depth, Field fd) {
		//不主动访问属性，除非方法内部引用到了它?
		Class<?> cls = fd.getDeclaringClass();
		if ("".equals(fd.getName()))
			if (int.class.equals(cls))
				Refs.visitAtt();
		{//访问属性本身
			RangesOfClsMember mmrange = RangesOfClsMember.getInst(depth, cls);
			if (mmrange != null) {
				mmrange.visited = true;
				ClsRange crange = mmrange.getClsRange(cls);
				FieldRange frange = crange.fieldMap.get(fd.getName());
				if (frange == null && fd.isSynthetic())
					return;
				frange.setVisited();
			}
		}
		if ("asdf".isEmpty()) {//访问属性名义类型
			Class<?> type = fd.getType();
			RangesOfClsMember type2 = RangesOfClsMember.getInst(depth, type);
			if (type2 != null) {
				type2.visited = true;
			}
		}
	}
	static int inc;
}